<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <script>
    // 用apply和call实现构造函数属性借用
    // function Car(brand, color, displacement) {
    //   this.brand = brand;
    //   this.color = color;
    //   this.displacement = displacement;
    // }
    // function Person(opt) {
    //   Car.apply(this, [opt.brand, opt.color, opt.displacement])
    //   this.name = opt.name
    //   this.age = opt.age
    //   this.say = function () {
    //     console.log(`${this.name}，${this.age}，${this.brand}、${this.color}、${this.displacement}`)
    //   }
    // }
    // var person = new Person({
    //   name: 'mashaod',
    //   age: 26,
    //   brand: "法拉利",
    //   color: 'red',
    //   displacement: 300
    // })
    // person.say()



    // 函数的链式调用jquery
    // person.run().morning().study().noon().afternoon().evening().night()
    // var person = {
    //   run: function () { console.log('run'); return this },
    //   morning: function () { console.log('morning'); return this },
    //   study: function () { console.log('study'); return this },
    //   noon: function () { console.log('noon'); return this },
    //   afternoon: function () { console.log('afternoon'); return this },
    //   evening: function () { console.log('evening'); return this },
    //   night: function () { console.log('night'); return this }
    // }
    // person.run().morning().study().noon().afternoon().evening().night()





    // 在使用person.run 访问属性时，其实，js引擎也是转化为person['run']去访问的




    // hasOwnProperty ==》 查找对象是否存在某个属性(只在自身查找)
    // function Car() {
    //   this.brand = '法拉利';
    //   this.color = 'red';
    //   this.displacement = 400;
    // }
    // Car.prototype = {
    //   lang: 4,
    //   widht: 2.5
    // }

    // Object.prototype.name = 'Object';

    // var car = new Car();

    // for (var i in car) { // 原型链上自己加的属性也会遍历到
    //   if (car.hasOwnProperty(i)) {
    //     console.log(car[i])
    //   }
    // }




    // var car = {
    //   brand: 'falal',
    //   color: "red"
    // }

    // console.log(car['displacement'])  // undefined
    // console.log('displacement' in car) // false
    // in 也可以用来判断，对象是否存在某个属性，但他会去原型链查找（如下），所以一般不用
    // function Car() {
    //   this.brand = 'falali'
    // }
    // Car.prototype.color = 'red'
    // var car = new Car()

    // console.log(car.hasOwnProperty('color'))
    // console.log('color' in car)






    // instancesof A对象的原型里到底有没有B的原型

    // function Car() { }
    // var car = new Car()

    // console.log(car instanceof Car)
    // console.log(car instanceof Object)
    // console.log([] instanceof Object)
    // console.log([] instanceof Array)
    // console.log({} instanceof Object)






    // 判断是不是数组
    // var a = [1, 2, 3]
    // console.log(a.constructor)
    // console.log(a instanceof Array)
    // var str = Object.prototype.toString.call(a)
    // if (str === '[object Array]') {
    //   console.log('是数组')
    // } else {
    //   console.log('不是数组')
    // }
    // console.log(a)
    // console.log(a.toString()) // 调用的是a.__proto__.toString()
    // console.log(Object.prototype.toString.call(a))//a.__proto__.__proto__.toString()



    // 实例化过程
    // function Car() {
    //   // this.__proto__ = Car.prototype
    //   this.name = 'mashaod'
    // }
    // var car = new Car()





    // 改变this指向

    // 全局this -> window
    // apply/call改变this执行
    // 构造函数的this执行实例化对象
    // 由谁调用则this指向谁




    // // callee
    // function test(a, b, c) {
    //   console.log(arguments.callee) // 是函数的本身
    //   console.log(arguments.callee.length) //test声明时想接收的参数
    //   console.log(test.length) // test 声明时想接收的参数
    //   console.log(arguments)// test调用时传入的参数
    // }
    // test(1, 2)



    // callee应用场景，在匿名函数中做递归
    // var sum = (function (n) {
    //   if (n <= 1) {
    //     return 1
    //   }
    //   return n + arguments.callee(n - 1)
    // })(100)
    // console.log(sum)


    // caller 谁在调用我
    // test2.caller,返回是在哪个函数中调用了test2，
    // 在全局调用则是null
    // function aaa() {
    //   test2()
    // }
    // function test2() {
    //   console.log(test2.caller)
    //   test3()
    // }
    // function test3() {
    //   console.log(test3.caller)
    // }
    // aaa()
    // test2()



    // 判断是一个数字
    // console.log(isNaN('1')) //隐式类型转换
    // console.log(isNaN('b'))


    // console.log(isNaN(NaN)) // true

    // console.log(typeof (NaN)) // number

    // var a = NaN;// 
    // if (typeof (a) === 'number' && !isNaN(a)) {
    //   console.log('是数字')
    // }
  </script>
</body>

</html>